﻿// (c) Copyright Fernando Cerqueira.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.ComponentModel.Design;
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
using AppRes = WindowsPhoneCommands.Resources;

namespace WindowsPhoneCommands
{
    /// <summary>
    /// This is the class that implements the package exposed by this assembly.
    ///
    /// The minimum requirement for a class to be considered a valid package for Visual Studio
    /// is to implement the IVsPackage interface and register itself with the shell.
    /// This package uses the helper classes defined inside the Managed Package Framework (MPF)
    /// to do it: it derives from the Package class that provides the implementation of the 
    /// IVsPackage interface and uses the registration attributes defined in the framework to 
    /// register itself and its components with the shell.
    /// </summary>
    // This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is
    // a package.
    [DefaultRegistryRoot(@"Software\Microsoft\VisualStudio\10.0")]
    [PackageRegistration(UseManagedResourcesOnly = true)]
    // This attribute is used to register the informations needed to show the this package
    // in the Help/About dialog of Visual Studio.
    [InstalledProductRegistration("#110", "#112", "2.0", IconResourceID = 400)]
    // This attribute is needed to let the shell know that this package exposes some menus.
    [ProvideMenuResource("Menus.ctmenu", 1)]
    // This attribute registers a tool window exposed by this package.
    [ProvideToolWindow(typeof(WpcTranslteToolWindow), Style = VsDockStyle.MDI, MultiInstances = true, Transient = true)]
    [ProvideToolWindow(typeof(WpcLocationToolWindow), Style = VsDockStyle.MDI, MultiInstances = true, Transient = true)]
    [ProvideToolWindow(typeof(WmAppManifestToolWindow), Style = VsDockStyle.MDI, MultiInstances = true, Transient = true)]
    [ProvideToolWindow(typeof(WpcMainToolWindow), Style = VsDockStyle.Tabbed, Orientation = ToolWindowOrientation.Left)]
    [ProvideAutoLoad(UIContextGuids80.NoSolution)]
    [Guid(GuidList.GuidWindowsPhoneCommandsPkgString)]
    public sealed class WindowsPhoneCommandsPackage : Package, IVsDebuggerEvents, IVsSolutionEvents, IVsUpdateSolutionEvents2
    {

        #region fields

        public DBGMODE DbgmodeNew = DBGMODE.DBGMODE_Design;
        public DTE2 EnvDte = GetGlobalService(typeof(SDTE)) as DTE2;
        public int TotalPhoneProjects { get; private set; }
        public int TotalProjects { get; private set; }

        private ToolWindowPane _mainWindowpane;
        private IVsSolution2 _solution;
        private uint _solutionEventsCookie;
        private IVsSolutionBuildManager2 _sbm;
        private uint _updateSolutionEventsCookie;
        private IVsDebugger _vsDebugger;
        private uint _debugEventsCookie;

        private double _currProject;
        private string _projectNameStartup;
        private bool _tryConnect;

        #endregion

        /// <summary>
        /// Default constructor of the package.
        /// Inside this method you can place any initialization code that does not require 
        /// any Visual Studio service because at this point the package object is created but 
        /// not sited yet inside Visual Studio environment. The place to do all the other 
        /// initialization is the Initialize method.
        /// </summary>
        public WindowsPhoneCommandsPackage()
        {
            Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", ToString()));
        }

        /// <summary>
        /// This function is called when the user clicks the menu item that shows the 
        /// tool window. See the Initialize method to see how the menu item is associated to 
        /// this function using the OleMenuCommandService service and the MenuCommand class.
        /// </summary>
        private void ShowToolWindow(object sender, EventArgs e)
        {
            // Get the instance number 0 of this tool window. This window is single instance so this instance
            // is actually the only one.
            // The last flag is set to true so that if the tool window does not exists it will be created.
            _mainWindowpane = FindToolWindow(typeof(WpcMainToolWindow), 0, true);
            if ((null == _mainWindowpane) || (null == _mainWindowpane.Frame))
            {
                throw new NotSupportedException(Resources.CanNotCreateWindow);
            }
            var windowFrame = (IVsWindowFrame)_mainWindowpane.Frame;
            ErrorHandler.ThrowOnFailure(windowFrame.Show());
        }

        /// <summary>
        /// Support method for finding an existing or creating a new tool window based on type and id.
        /// </summary>
        /// <typeparam name="T">type of MDI tool window</typeparam>
        /// <param name="id">id of tool window</param>
        /// <returns>the tool window pane</returns>
        public ToolWindowPane CreateWindow<T>(int id)
        {
            //find existing tool window based on id
            var window = FindToolWindow(typeof(T), id, false);

            if (window == null)
            {
                //create a new window with explicit tool window id
                window = FindToolWindow(typeof(T), id, true);
                if ((null == window) || (null == window.Frame))
                {
                    throw new NotSupportedException(Resources.CanNotCreateWindow);
                }
            }
            ShowWindow(window);
            return window;

        }

        public object GetServiceHelper(Type type)
        {
            return GetService(type);
        }

        public void ShowWindow(ToolWindowPane window)
        {
            var windowFrame = (IVsWindowFrame)window.Frame;
            ErrorHandler.ThrowOnFailure(windowFrame.Show());
        }

        public void CloseWindow(ToolWindowPane window)
        {
            if (window == null) return;
            var windowFrame = (IVsWindowFrame)window.Frame;
            ErrorHandler.ThrowOnFailure(windowFrame.CloseFrame((int)__FRAMECLOSE.FRAMECLOSE_NoSave));
        }

        internal string StatusConnect
        {
            get
            {
                switch (DbgmodeNew)
                {
                    case DBGMODE.DBGMODE_Design:
                        {
                            if (WPhoneDevice.IsConnected)
                            {
                                return Resources.Connected;
                            }
                            return Resources.Disconnected;
                        }
                    case DBGMODE.DBGMODE_Break:
                        {
                            if (WPhoneDevice.IsConnected)
                            {
                                return Resources.Connected + " " + Resources.DebugBreak;
                            }
                            return Resources.Disconnected + " " + Resources.DebugBreak;
                        }
                    case DBGMODE.DBGMODE_Enc:
                    case DBGMODE.DBGMODE_EncMask:
                        {
                            if (WPhoneDevice.IsConnected)
                            {
                                return Resources.Connected + " " + Resources.DebugEnc;
                            }
                            return Resources.Disconnected + " " + Resources.DebugEnc;
                        }
                    case DBGMODE.DBGMODE_Run:
                        {
                            if (WPhoneDevice.IsConnected)
                            {
                                return Resources.Connected + " " + Resources.DebugRun;
                            }
                            return Resources.Disconnected + " " + Resources.DebugRun;
                        }
                }
                return Resources.DebugError;
            }
        }


        /////////////////////////////////////////////////////////////////////////////
        // Overriden Package Implementation
        #region Package Members

        /// <summary>
        /// Initialization of the package; this method is called right after the package is sited, so this is the place
        /// where you can put all the initilaization code that rely on services provided by VisualStudio.
        /// </summary>
        protected override void Initialize()
        {
            Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", ToString()));
            base.Initialize();

            // Add our command handlers for menu (commands must exist in the .vsct file)
            var mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
            if (null != mcs)
            {
                // Create the command for the other windows 
                var menuCommandId = new CommandID(GuidList.GuidWindowsPhoneCommandsCmdSet, (int)PkgCmdIDList.cmdidWPCommands);
                var menuOtherWin = new MenuCommand(ShowToolWindow, menuCommandId);
                mcs.AddCommand(menuOtherWin);

                // Create the command for the tool window
                var toolwndCommandId = new CommandID(GuidList.GuidWindowsPhoneCommandsCmdSet, (int)PkgCmdIDList.cmdidWPCommandsTool);
                var menuToolWin = new MenuCommand(ShowToolWindow, toolwndCommandId);
                mcs.AddCommand(menuToolWin);


                // Create the command for the edit manifet menu item.
                var editManifestCmdItemId = new CommandID(GuidList.GuidDynamicMenuEditManifestCommandItemProjectCmdSet, (int)PkgCmdIDList.cmdidEditManifest);
                var editManifetMenuItemCommand = new OleMenuCommand(EditManifestMenuCommandItemExecuteQueryStatus, editManifestCmdItemId);
                mcs.AddCommand(editManifetMenuItemCommand);
                editManifetMenuItemCommand.BeforeQueryStatus += EditManifestMenuCommandItemBeforeQueryStatus;

                // Create the command for the edit manifet menu project.
                var editManifetCmdPrjdId = new CommandID(GuidList.GuidDynamicMenuEditManifestCommandProjectCmdSet, (int)PkgCmdIDList.cmdidEditManifest);
                var editManifetMenuPrjCommand = new OleMenuCommand(EditManifestMenuCommandPrjExecuteQueryStatus, editManifetCmdPrjdId);
                mcs.AddCommand(editManifetMenuPrjCommand);
                editManifetMenuPrjCommand.BeforeQueryStatus += EditManifestMenuCommandPrjBeforeQueryStatus;


                // Create the command for the create files resource menu item.
                var createResxCmdItemId = new CommandID(GuidList.GuidDynamicMenuEditManifestCommandItemProjectCmdSet, (int)PkgCmdIDList.cmdidCreateLocation);
                var createResxMenuItemCommand = new OleMenuCommand(CreateResxMenuCommandPrjExecuteQueryStatus, createResxCmdItemId);
                mcs.AddCommand(createResxMenuItemCommand);
                createResxMenuItemCommand.BeforeQueryStatus += CreateResxMenuCommandItemBeforeQueryStatus;

                
                // Create the command for the create files resource menu project.
                var createResxCmdPrjdId = new CommandID(GuidList.GuidDynamicMenuEditManifestCommandProjectCmdSet, (int)PkgCmdIDList.cmdidCreateLocation);
                var createResxMenuPrjCommand = new OleMenuCommand(CreateResxMenuCommandPrjExecuteQueryStatus, createResxCmdPrjdId);
                mcs.AddCommand(createResxMenuPrjCommand);
                createResxMenuPrjCommand.BeforeQueryStatus += CreateResxMenuCommandPrjBeforeQueryStatus;

                // Create the command for the translate files resource menu item.
                var translateResxCmdItemId = new CommandID(GuidList.GuidDynamicMenuEditManifestCommandItemProjectCmdSet, (int)PkgCmdIDList.cmdidTranslateResx);
                var translateResxMenuItemCommand = new OleMenuCommand(CreateResxMenuCommandPrjExecuteQueryStatus, translateResxCmdItemId);
                mcs.AddCommand(translateResxMenuItemCommand);
                translateResxMenuItemCommand.BeforeQueryStatus += TranslateResxMenuCommandItemBeforeQueryStatus;


                // Create the command for the translate files resource menu project.
                var translateResxCmdPrjdId = new CommandID(GuidList.GuidDynamicMenuEditManifestCommandProjectCmdSet, (int)PkgCmdIDList.cmdidTranslateResx);
                var translateResxMenuPrjCommand = new OleMenuCommand(CreateResxMenuCommandPrjExecuteQueryStatus, translateResxCmdPrjdId);
                mcs.AddCommand(translateResxMenuPrjCommand);
                translateResxMenuPrjCommand.BeforeQueryStatus += TranslateResxMenuCommandPrjBeforeQueryStatus;

            }

            // Get solution
            _solution = ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution)) as IVsSolution2;
            if (_solution != null)
            {
                object count;
                _solution.GetProperty((int)__VSPROPID.VSPROPID_ProjectCount, out count);

                // Register for solution events
                _solution.AdviseSolutionEvents(this, out _solutionEventsCookie);
            }

            // Get solution build manager
            _sbm =
                ServiceProvider.GlobalProvider.GetService(typeof(SVsSolutionBuildManager)) as IVsSolutionBuildManager2;
            if (_sbm != null)
            {
                _sbm.AdviseUpdateSolutionEvents(this, out _updateSolutionEventsCookie);
            }

            // get Debuger Manager
            _vsDebugger = ServiceProvider.GlobalProvider.GetService(typeof(IVsDebugger)) as IVsDebugger;
            if (_vsDebugger != null)
            {
                _vsDebugger.AdviseDebuggerEvents(this, out _debugEventsCookie);
            }

        }

        protected override void Dispose(bool disposing)
        {
            if (_solution != null && _solutionEventsCookie != 0)
            {
                _solution.UnadviseSolutionEvents(_solutionEventsCookie);
                _solution = null;
            }

            if (_sbm != null && _updateSolutionEventsCookie != 0)
            {
                _sbm.UnadviseUpdateSolutionEvents(_updateSolutionEventsCookie);
                _sbm = null;
            }

            if (_vsDebugger != null && _debugEventsCookie != 0)
            {
                _vsDebugger.UnadviseDebuggerEvents(_debugEventsCookie);
                _vsDebugger = null;
            }

            _mainWindowpane = null;

            base.Dispose(disposing);
        }

        private  void LaunchEditManifest(Project project,string itempath)
        {
            var ivsol = GetService(typeof(SVsSolution)) as IVsSolution;
            var prjid = EnvPhoneDevice.GetProjectGuid(ivsol, project);

            var window = (WmAppManifestToolWindow)CreateWindow<WmAppManifestToolWindow>(Math.Abs(prjid.ToString().GetHashCode() - PkgCmdIDList.cmdidEditManifest.GetHashCode()));

            window.OwnerProject = project.Name;
            window.WmAppManifestFilePath = itempath;

            var ver = project.Properties.Item("AssemblyVersion").Value.ToString();
            if (ver.EndsWith("*"))
            {
                ver = ver.Replace(".*", "");
            }

            window.AssemblyProject = ver;

            ShowWindow(window);
        }

        private void EditManifestMenuCommandItemExecuteQueryStatus(object sender, EventArgs e)
        {
            var project = EnvPhoneDevice.GetCurrentProject(EnvDte);
            var solutionExplorer = EnvDte.ToolWindows.SolutionExplorer;
            var items = solutionExplorer.SelectedItems as Array;
            if (items == null || items.Length != 1)
            {
                return;
            }
            var itemPath = String.Empty;
            foreach (var prjItem in (from UIHierarchyItem hierarchyItem in items select hierarchyItem.Object).OfType<ProjectItem>())
            {
                itemPath = prjItem.Properties.Item("FullPath").Value.ToString();
            }
            LaunchEditManifest(project, itemPath);
        }

        private void EditManifestMenuCommandItemBeforeQueryStatus(object sender, EventArgs e)
        {
            var menuCommand = sender as OleMenuCommand;
            if (menuCommand != null)
            {
                if (EnvDte.SelectedItems.Count != 1)
                {
                    menuCommand.Visible = false;
                    return;
                }

                IntPtr hierarchyPtr, selectionContainerPtr;
                uint projectItemId;
                IVsMultiItemSelect mis;

                var monitorSelection = (IVsMonitorSelection)GetService(typeof(SVsShellMonitorSelection));
                monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);

                var hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;

                if (hierarchy != null)
                {
                    if (EnvPhoneDevice.IsPhoneProject(hierarchy))
                    {
                        object value;
                        hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_Name, out value);

                        if (value != null && value.ToString().ToLower() == "wmappmanifest.xml")
                        {
                            menuCommand.Visible = true;
                        }
                        else
                        {
                            menuCommand.Visible = false;
                        }
                    }
                    else
                    {
                        menuCommand.Visible = false;
                    }
                }
            }
        }

        private void EditManifestMenuCommandPrjExecuteQueryStatus(object sender, EventArgs e)
        {
            var project = EnvPhoneDevice.GetCurrentProject(EnvDte);
            var solutionExplorer = EnvDte.ToolWindows.SolutionExplorer;
            var items = solutionExplorer.SelectedItems as Array;
            if (items == null || items.Length != 1)
            {
                return;
            }
            var itemPath = EnvPhoneDevice.GetPathFileManifest(project);
            LaunchEditManifest(project, itemPath);
        }

        private void EditManifestMenuCommandPrjBeforeQueryStatus(object sender, EventArgs e)
        {
            var menuCommand = sender as OleMenuCommand;
            if (menuCommand != null)
            {
                if (EnvDte.SelectedItems.Count != 1)
                {
                    menuCommand.Visible = false;
                    return;
                }

                IntPtr hierarchyPtr, selectionContainerPtr;
                uint projectItemId;
                IVsMultiItemSelect mis;

                var monitorSelection = (IVsMonitorSelection)GetService(typeof(SVsShellMonitorSelection));
                monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);

                var hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;

                if (hierarchy != null)
                {
                    if (EnvPhoneDevice.IsPhoneProject(hierarchy))
                    {
                        var project = EnvPhoneDevice.GetCurrentProject(EnvDte);
                        var item = EnvPhoneDevice.GetProjectManifestWp(project);
                        menuCommand.Visible = item != null;
                    }
                    else
                    {
                        menuCommand.Visible = false;
                    }
                }
            }
        }

        private void ResxMenuCommandPrjBeforeQueryStatus(object sender)
        {
            var menuCommand = sender as OleMenuCommand;
            if (menuCommand == null) return;

            var project = EnvPhoneDevice.GetCurrentProject(EnvDte);
            var solutionExplorer = EnvDte.ToolWindows.SolutionExplorer;
            var items = solutionExplorer.SelectedItems as Array;
            if (items == null || items.Length != 1)
            {
                menuCommand.Visible = false;
                return;
            }
            var ivsol = GetService(typeof(SVsSolution)) as IVsSolution;

            menuCommand.Visible = EnvPhoneDevice.IsPhoneProject(ivsol, project);
        }

        private void CreateResxMenuCommandPrjBeforeQueryStatus(object sender, EventArgs e)
        {
            ResxMenuCommandPrjBeforeQueryStatus(sender);
        }

        private void TranslateResxMenuCommandPrjBeforeQueryStatus(object sender, EventArgs e)
        {
            TranslateResxPrjBeforeQueryStatus(sender);
        }

        private void TranslateResxPrjBeforeQueryStatus(object sender)
        {
            var menuCommand = sender as OleMenuCommand;
            if (menuCommand != null)
            {
                if (EnvDte.SelectedItems.Count != 1)
                {
                    menuCommand.Visible = false;
                    return;
                }

                IntPtr hierarchyPtr, selectionContainerPtr;
                uint projectItemId;
                IVsMultiItemSelect mis;

                var monitorSelection = (IVsMonitorSelection)GetService(typeof(SVsShellMonitorSelection));
                monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);

                var hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;

                if (hierarchy != null)
                {
                    if (EnvPhoneDevice.IsCSharpProject(hierarchy) || EnvPhoneDevice.IsVbProject(hierarchy))
                    {
                        menuCommand.Visible = true;
                    }
                    else
                    {
                        menuCommand.Visible = false;
                    }
                }
            }
        }

        private void ResxMenuItemBeforeQueryStatus(object sender)
        {
            var menuCommand = sender as OleMenuCommand;
            if (menuCommand != null)
            {
                if (EnvDte.SelectedItems.Count != 1)
                {
                    menuCommand.Visible = false;
                    return;
                }

                IntPtr hierarchyPtr, selectionContainerPtr;
                uint projectItemId;
                IVsMultiItemSelect mis;

                var monitorSelection = (IVsMonitorSelection)GetService(typeof(SVsShellMonitorSelection));
                monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);

                var hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;

                if (hierarchy != null)
                {
                    //windows phone C#/VB Template Project
                    if (EnvPhoneDevice.IsPhoneProject(hierarchy))
                    {
                        object value;
                        hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_Name, out value);

                        if (value != null && value.ToString().ToLower().EndsWith(".resx"))
                        {
                            menuCommand.Visible = true;
                        }
                        else
                        {
                            menuCommand.Visible = false;
                        }
                    }
                    else
                    {
                        menuCommand.Visible = false;
                    }
                }
            }
        }

        private void TranslateResxMenuItemBeforeQueryStatus(object sender)
        {
            var menuCommand = sender as OleMenuCommand;
            if (menuCommand != null)
            {
                if (EnvDte.SelectedItems.Count != 1)
                {
                    menuCommand.Visible = false;
                    return;
                }

                IntPtr hierarchyPtr, selectionContainerPtr;
                uint projectItemId;
                IVsMultiItemSelect mis;

                var monitorSelection = (IVsMonitorSelection)GetService(typeof(SVsShellMonitorSelection));
                monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);

                var hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;

                if (hierarchy != null)
                {
                    if (EnvPhoneDevice.IsCSharpProject(hierarchy) || EnvPhoneDevice.IsVbProject(hierarchy))
                    {
                        object value;
                        hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_Name, out value);

                        if (value != null && value.ToString().ToLower().EndsWith(".resx"))
                        {
                            menuCommand.Visible = true;
                        }
                        else
                        {
                            menuCommand.Visible = false;
                        }
                    }
                    else
                    {
                        menuCommand.Visible = false;
                    }
                }
            }
        }

        private void TranslateResxMenuCommandItemBeforeQueryStatus(object sender, EventArgs e)
        {
            TranslateResxMenuItemBeforeQueryStatus(sender);
        }

        private void CreateResxMenuCommandItemBeforeQueryStatus(object sender, EventArgs e)
        {
            ResxMenuItemBeforeQueryStatus(sender);
        }

        private void CreateResxMenuCommandPrjExecuteQueryStatus(object sender, EventArgs e)
        {
            var ivsol = GetService(typeof(SVsSolution)) as IVsSolution;
            var project = EnvPhoneDevice.GetCurrentProject(EnvDte);

            var prjid = EnvPhoneDevice.GetProjectGuid(ivsol, project);

            var cmd = (OleMenuCommand) sender;
            if (cmd.CommandID.ID == PkgCmdIDList.cmdidCreateLocation)
            {
                var window = (WpcLocationToolWindow)CreateWindow<WpcLocationToolWindow>(Math.Abs(prjid.ToString().GetHashCode() - PkgCmdIDList.cmdidCreateLocation.GetHashCode()));

                window.OwnerProject = project.Name;
                window.NeutralResource = EnvPhoneDevice.GetNeutralResourcesLanguage(project);
                window.SupportedCultures = EnvPhoneDevice.GetSupportedCultures(project).Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                ShowWindow(window);
            }
            if (cmd.CommandID.ID == PkgCmdIDList.cmdidTranslateResx)
            {

                var window = (WpcTranslteToolWindow)CreateWindow<WpcTranslteToolWindow>(Math.Abs(prjid.ToString().GetHashCode() - PkgCmdIDList.cmdidTranslateResx.GetHashCode()));

                window.OwnerProject = project.Name;
                window.NeutralResource = EnvPhoneDevice.GetNeutralResourcesLanguage(project);
                window.SupportedCultures = EnvPhoneDevice.GetSupportedCultures(project).Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                if (EnvDte.SelectedItems.Count == 1)
                {
                    window.SelectedResource = null;
                    if (EnvDte.SelectedItems.Item(1).ProjectItem != null)
                    {
                        window.SelectedResource = EnvDte.SelectedItems.Item(1).ProjectItem.Properties.Item("FullPath").Value.ToString();
                    }
                    return;
                }

                ShowWindow(window);
            }
        }

        private void CloseToolWindows(IVsHierarchy pHierarchy)
        {
            Guid projectGuid;
            ErrorHandler.Succeeded(
                pHierarchy.GetGuidProperty(
                    VSConstants.VSITEMID_ROOT,
                    (int)__VSHPROPID.VSHPROPID_ProjectIDGuid,
                    out projectGuid));

            if (projectGuid != new Guid())
            {
                //manifest tool window
                var id = Math.Abs(projectGuid.ToString().GetHashCode() - PkgCmdIDList.cmdidEditManifest.GetHashCode());
                var window = FindToolWindow(typeof(WmAppManifestToolWindow), id, false);
                if (window != null)
                {
                    CloseWindow(window);
                }

                //location tool window
                id = Math.Abs(projectGuid.ToString().GetHashCode() - PkgCmdIDList.cmdidCreateLocation.GetHashCode());
                window = FindToolWindow(typeof(WpcLocationToolWindow), id, false);
                if (window != null)
                {
                    CloseWindow(window);
                }

                //translate tool window
                id = Math.Abs(projectGuid.ToString().GetHashCode() - PkgCmdIDList.cmdidTranslateResx.GetHashCode());
                window = FindToolWindow(typeof(WpcTranslteToolWindow), id, false);
                if (window != null)
                {
                    CloseWindow(window);
                }
            }
        }

        #endregion

        #region Implementation of IVsDebuggerEvents

        public int OnModeChange(DBGMODE dbgmodeNew)
        {
            DbgmodeNew = dbgmodeNew;

            if (_mainWindowpane != null)
            {
                if (((IVsWindowFrame)_mainWindowpane.Frame).IsVisible() == VSConstants.S_OK)
                {
                    ((WpcMainToolWindow)_mainWindowpane).ShowInfoEnvDevice();
                }
            }

            if (_tryConnect)
            {
                _tryConnect = false;
                if (_mainWindowpane != null)
                {
                    if (((IVsWindowFrame)_mainWindowpane.Frame).IsVisible() == VSConstants.S_OK)
                    {
                        ((WpcMainToolWindow)_mainWindowpane).ConnectDebug();
                    }
                }
            }

            return VSConstants.S_OK;
        }

        #endregion

        #region Implementation of IVsSolutionEvents

        public int OnAfterCloseSolution(object pUnkReserved)
        {
            // Reset progress bar after closing solution
            TotalPhoneProjects = 0;
            TotalProjects = 0;
            if (_mainWindowpane != null)
            {
                if (((IVsWindowFrame)_mainWindowpane.Frame).IsVisible() == VSConstants.S_OK)
                {
                    ((WpcMainToolWindow)_mainWindowpane).ResetBuild();
                    ((WpcMainToolWindow)_mainWindowpane).UpdateMenu(false);
                }
            }
            return VSConstants.S_OK;
        }

        public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded)
        {
            // Track the number of phone open projects
            if (EnvPhoneDevice.IsValidProject(pHierarchy))
            {
                TotalProjects++;
            }
            if (EnvPhoneDevice.IsPhoneProject(pHierarchy))
            {
                TotalPhoneProjects++;
            }
            return VSConstants.S_OK;
        }

        public int OnBeforeCloseProject(IVsHierarchy pHierarchy, int fRemoved)
        {
            // Track the number of phone open projects
            if (EnvPhoneDevice.IsValidProject(pHierarchy))
            {
                TotalProjects--;
            }
            if (EnvPhoneDevice.IsPhoneProject(pHierarchy))
            {
                    TotalPhoneProjects--;
            }

            if (_mainWindowpane != null)
            {
                if (((IVsWindowFrame)_mainWindowpane.Frame).IsVisible() == VSConstants.S_OK)
                {
                    ((WpcMainToolWindow)_mainWindowpane).UpdateMenu(TotalPhoneProjects > 0);
                }
            }

            CloseToolWindows(pHierarchy);

            return VSConstants.S_OK;
        }

        public int OnAfterOpenSolution(object pUnkReserved, int fNewSolution)
        {
            _mainWindowpane = FindToolWindow(typeof(WpcMainToolWindow), 0, true);

            if (_mainWindowpane != null)
            {
                if (((IVsWindowFrame)_mainWindowpane.Frame).IsVisible() == VSConstants.S_OK)
                {
                    ((WpcMainToolWindow)_mainWindowpane).UpdateMenu(TotalPhoneProjects > 0);
                }
            }
            return VSConstants.S_OK;
        }

        #region no code


        public int OnQueryCloseProject(IVsHierarchy pHierarchy, int fRemoving, ref int pfCancel)
        {
            return VSConstants.S_OK;
        }

        public int OnAfterLoadProject(IVsHierarchy pStubHierarchy, IVsHierarchy pRealHierarchy)
        {
            return VSConstants.S_OK;
        }

        public int OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int pfCancel)
        {
            return VSConstants.S_OK;
        }

        public int OnBeforeUnloadProject(IVsHierarchy pRealHierarchy, IVsHierarchy pStubHierarchy)
        {
            return VSConstants.S_OK;
        }

        public int OnQueryCloseSolution(object pUnkReserved, ref int pfCancel)
        {
            return VSConstants.S_OK;
        }

        public int OnBeforeCloseSolution(object pUnkReserved)
        {
            return VSConstants.S_OK;
        }

        #endregion

        #endregion

        #region IVsUpdateSolutionEvents2 Members

        int IVsUpdateSolutionEvents2.UpdateProjectCfg_Begin(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln,
                                                            uint dwAction, ref int pfCancel)
        {
            // This method is called when a specific project begins building.  Based on the total number of open projects, we can estimate
            // how far along in the build we are.
            _currProject++;

            if (_mainWindowpane != null)
            {
                // Update progress bar text
                object o;
                pHierProj.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_Name, out o);
                var name = o as string;

                if (((IVsWindowFrame)_mainWindowpane.Frame).IsVisible() == VSConstants.S_OK)
                {
                    ((WpcMainToolWindow)_mainWindowpane).BuildSolutionStatus(name, _currProject, TotalProjects);
                }
            }

            return VSConstants.S_OK;
        }


        int IVsUpdateSolutionEvents.UpdateSolution_Begin(ref int pfCancelUpdate)
        {
            //find startup project when F5
            _projectNameStartup = String.Empty;
            IVsHierarchy ppHierarchy;
            _sbm.get_StartupProject(out ppHierarchy);
            if (EnvPhoneDevice.IsPhoneProject(ppHierarchy))
            {
                object o;
                ppHierarchy.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_Name, out o);
                _projectNameStartup = (string)o;
            }

            _tryConnect = false;

            // This method is called when the entire solution starts to build.
            _currProject = 0;

            if (_mainWindowpane != null)
            {
                if (((IVsWindowFrame)_mainWindowpane.Frame).IsVisible() == VSConstants.S_OK)
                {
                    ((WpcMainToolWindow)_mainWindowpane).StartSolutionBuild();
                }
                if (!String.IsNullOrEmpty(_projectNameStartup))
                {
                    //update cache names app
                    var wm = EnvPhoneDevice.ReadWmAppManifest(EnvDte, _projectNameStartup);
                    if (wm != null)
                    {
                        EnvPhoneDevice.UpdateCacheApp(wm.Title, wm.Title, wm.ProductId);
                    }
                    _tryConnect = true;
                }
            }
            return VSConstants.S_OK;
        }

        int IVsUpdateSolutionEvents.UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand)
        {
            // This method is called when the entire solution is done building.
            if (_mainWindowpane != null)
            {
                if (fSucceeded != 0)
                {
                    if (((IVsWindowFrame)_mainWindowpane.Frame).IsVisible() == VSConstants.S_OK)
                    {
                        ((WpcMainToolWindow)_mainWindowpane).EndSolutionBuild(AppRes.Buildcompleted);
                    }
                }
                else if (fCancelCommand != 0)
                {
                    if (((IVsWindowFrame)_mainWindowpane.Frame).IsVisible() == VSConstants.S_OK)
                    {
                        ((WpcMainToolWindow)_mainWindowpane).EndSolutionBuild(AppRes.BuildCanceled);
                    }
                    _tryConnect = false;
                }
            }
            return VSConstants.S_OK;
        }

        #region no code

        int IVsUpdateSolutionEvents2.UpdateProjectCfg_Done(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln,
                                                   uint dwAction, int fSuccess, int fCancel)
        {
            return VSConstants.S_OK;
        }

        int IVsUpdateSolutionEvents2.OnActiveProjectCfgChange(IVsHierarchy pIVsHierarchy)
        {
            return VSConstants.S_OK;
        }

        int IVsUpdateSolutionEvents2.UpdateSolution_Begin(ref int pfCancelUpdate)
        {
            return VSConstants.S_OK;
        }

        int IVsUpdateSolutionEvents2.UpdateSolution_Cancel()
        {
            return VSConstants.S_OK;
        }

        int IVsUpdateSolutionEvents2.UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand)
        {
            return VSConstants.S_OK;
        }

        int IVsUpdateSolutionEvents2.UpdateSolution_StartUpdate(ref int pfCancelUpdate)
        {
            return VSConstants.S_OK;
        }

        int IVsUpdateSolutionEvents.OnActiveProjectCfgChange(IVsHierarchy pIVsHierarchy)
        {
            return VSConstants.S_OK;
        }

        int IVsUpdateSolutionEvents.UpdateSolution_Cancel()
        {
            return VSConstants.S_OK;
        }

        int IVsUpdateSolutionEvents.UpdateSolution_StartUpdate(ref int pfCancelUpdate)
        {
            return VSConstants.S_OK;
        }

        #endregion

        #endregion

    }
}
